package pl.ydp.components.mathcell.mathrecognizer.geometry.classification
{
	import pl.ydp.components.mathcell.mathrecognizer.geometry.VectorDirection;
	

	public final class PrimitiveType
	{
		
		public static function getObjectFromDirection(dir:Number):Number{
			
			if (dir < 4){
				return dir;
			}  else {
				return dir - 4;
			}	
		}
		
		
		public static function areOrthogonal(pt1:Number, pt2:Number):Boolean{
			
			if ((pt1 & LINE)  &&  (pt2 & LINE)){
				pt1 = pt1-LINE;
				pt2 = pt2-LINE;
				
				if (pt1 > pt2){
					var tmp:Number = pt2;
					pt2 = pt1;
					pt1 = tmp;
				}
				
				if (pt2/pt1 == (LINE2-LINE)/(LINE0-LINE)){
					return true;
				} else {
					return false;
				}
				
			}
			
			return false;
		}
		
		public static function areSimilar(pt1:Number, pt2:Number):Boolean{
			
			if (pt1 == pt2){
				return true;
			} else if ((pt1 & LINE)  &&  (pt2 & LINE)){
				pt1 = pt1-LINE;
				pt2 = pt2-LINE;
				
				if (pt1 > pt2){
					var tmp:Number = pt2;
					pt2 = pt1;
					pt1 = tmp;
				}
				
				if (pt2/pt1 == (LINE2-LINE)/(LINE0-LINE)){
					return false;
				} else {
					return true;
				}
				
			} else if ((pt1 & CURVE)  &&  (pt2 & CURVE)){
				return true;
			} else if ((pt1 & CURVE)  &&  (pt2 & LINE)){
				return true;
			} else {
				return false;
			}
			
			return false;
		}
		
		public static function primitiveCurveTypeFromDirections(begin:Number, end:Number):Number{
			var dir:Number = CURVE;
			var d:Number;
			
			if (end >= begin){
				for (d = begin ; d <= end ; d ++){
					dir = dir | _CURVE_BASE*Math.pow(2,d);
				}
			} else {
				for (d = begin ; d <= VectorDirection.MAX ; d ++){
					dir = dir | _CURVE_BASE*Math.pow(2,d);
				}
				for (d = VectorDirection.MIN ; d <= end ; d ++){
					dir = dir | _CURVE_BASE*Math.pow(2,d);
				}
			}
			
			return dir;
			
		}
		
		
		public static function isCurve(pt:Number):Boolean{
			return ((pt & CURVE) != 0);
		}
		
		public static function isLine(pt:Number):Boolean{
			return ((pt & LINE) != 0);
		}
		public static function isWave(pt:Number):Boolean{
			return ((pt & WAVE) != 0);
		}
		
		public static function isLoop(pt:Number):Boolean{
			return ((pt & LOOP) != 0);
		}
		
		public static const NONE:Number 	= 1;
		public static const UNKNOWN:Number 	= 1;
		
		public static const LINE:Number  = 16;
		
		public static const LINE0:Number = 16*4 + LINE;
		public static const LINE1:Number = 16*8 + LINE;
		public static const LINE2:Number = 16*16 + LINE;
		public static const LINE3:Number = 16*32+ LINE;
		
		public static const CURVE:Number 		= 1048576;
		
		private static const _CURVE_BASE:Number = 1024
		private static const _CURVE0:Number 	= 1024*1;
		private static const _CURVE1:Number 	= 1024*2;
		private static const _CURVE2:Number 	= 1024*4;
		private static const _CURVE3:Number 	= 1024*8;
		private static const _CURVE4:Number 	= 1024*16;
		private static const _CURVE5:Number 	= 1024*32;
		private static const _CURVE6:Number 	= 1024*64;
		private static const _CURVE7:Number 	= 1024*128;
		
		public static const CURVE_01:Number		= CURVE | _CURVE0|_CURVE1;
		public static const CURVE_12:Number		= CURVE | _CURVE1|_CURVE2;
		public static const CURVE_23:Number		= CURVE | _CURVE2|_CURVE3;
		public static const CURVE_34:Number		= CURVE | _CURVE3|_CURVE4;
		public static const CURVE_45:Number		= CURVE | _CURVE4|_CURVE5;
		public static const CURVE_56:Number		= CURVE | _CURVE5|_CURVE6;
		public static const CURVE_67:Number		= CURVE | _CURVE6|_CURVE7;
		public static const CURVE_70:Number		= CURVE | _CURVE7|_CURVE0;
		
		public static const CURVE_MASK:Number	= CURVE | _CURVE0 | _CURVE1 | _CURVE2 | _CURVE3 | _CURVE4 | _CURVE5 | _CURVE6 | _CURVE7;
		
		private static const _CURVE_HELIX:Number 		= CURVE | 1024*(256-1);
		
		public static const CURVE_NORTH:Number 	= CURVE | _CURVE7|_CURVE0|_CURVE1; // 5,6,7 -> 1,2,3
		public static const CURVE_SOUTH:Number 	= CURVE | _CURVE3|_CURVE4|_CURVE5; // 1,2,3 -> 5,6,7
		public static const CURVE_WEST:Number  	= CURVE | _CURVE5|_CURVE6|_CURVE7; // 3,4,5 -> 7,0,1 
		public static const CURVE_EAST:Number 	= CURVE | _CURVE1|_CURVE2|_CURVE3; // 7,0,1 -> 3,4,5
		
		public static const CURVE_NE:Number 	= CURVE | _CURVE0|_CURVE1|_CURVE2;
		public static const CURVE_NW:Number 	= CURVE | _CURVE6|_CURVE7|_CURVE0;
		public static const CURVE_SE:Number 	= CURVE | _CURVE2|_CURVE3|_CURVE4;
		public static const CURVE_SW:Number 	= CURVE | _CURVE4|_CURVE5|_CURVE6;
		
		public static const DOT:Number 	= 2097152*1;
		
		public static const HELIX:Number= 2097152*2 | _CURVE_HELIX;
		
		public static const LOOP:Number = 2097152*4;
		
		public static const FLOURISH:Number = 2097152*8;  
		
		public static const WAVE:Number = 2097152*16;
		

	}
}